<template>
    <div>
        <!-- 选项式Api (OptionsApi) -->
        <h4>组合式API(CompositionApi)-语法</h4>
        <ul>
            <li>单文件组件提供三种组件构建语法：单选项式,单组合式,选项组合混合式</li>
            <li>
                组合式响应式数据定义：通过内置方法 reactive 完成对象、数组数据的劫持，页面模板使用直接调用即可，JS中直接使用 <br>
                    + reactive 不能对基本数据类型 进行数据劫持<br>
                    + reactive 构建的对象因为数据对象值的本身作为劫持对象操作，所以不能重置，一旦重置将丢失响应式<br>
                    + 因为上述两个原因，所以vue提供 ref 完成劫持对象定义，通过value属性指向数据值，解决这些问题 <br>
            </li>
            <li>组合式响应式数据定义：通过内置方法 ref 完成数据劫持，页面模板使用直接调用即可，JS中需要通过value获取值</li>
            <li>组合式计算数据定义：通过内置方法 computed 完成计算属性描述，定义规则和选项式相同，页面模板使用直接调用即可，JS中需要通过value获取值</li>
            <li>
                组合式侦听器的定义：通过内置方法 watch 完成对应变量的监听<br>
                方法：watch(tagVar|tagCallback,callback,options) <br>
                    + tarVar 被监控的变量(响应式数据变量，计算属性); <br>
                    + tagCallback 提供回调函数，通过回调函数返回值完成对应单个或多个变量的监控; <br>
                    + callback 变量发生变化时的回调执行方法 <br>
                    + options 监控器的详细扩展配置 （deep immediate）
            </li>
        </ul>
        <h5>ref的响应数据构建</h5>
        <p>info:{{ info }}</p>
        <input type="text" v-model="info">
        <p>user:{{ user }}</p>
        <input v-model="user[0]" type="text" />
        <input type="button" value="addItem" @click="addUserItem()">
        <p :style="`color:${color}`">颜色样式的绑定</p>
        <input v-model="color" type="color" />
        <hr>

        <h5>computed的响应数据构建</h5>、
        <p>msg:{{ msg }}</p>
        <input v-model="msg" type="text" />
        <p>newMsg:{{ newMsg }}</p>
        <input v-model="newMsg" type="text" />
        <input type="button" value="打印计算属性值" @click="printNewMsg()">
        <hr>

        <h5>reactive的响应式数据构建</h5>
        <p>stu:{{ stu }}</p>
        <p>stu.name:{{ stu.name }}</p>
        <p>stu['password']:{{ stu['password'] }}</p>
        <input v-model="stu.name" type="text" />
        <input v-model="stu['password']" type="text" />
        <input type="button" value="打印stu.name" @click="printStuName()">
        <input type="button" value="对reactive进行响应式丢失操作" @click="resetStu()">
        <hr>

        <h5>侦听器的构建</h5>
        <p>text:{{ text }}</p>
        <input v-model="text" type="text" /> <br><br>
        <p>obj:{{ obj }}</p>
        <input v-model="obj.a" type="text" />
        <input v-model="obj.b" type="text" />
        <input type="button" value="重置obj" @click=" obj={ a:'aa',b:'bb' } ">
        <input type="button" value="关闭obj.a侦听器" @click=" stopWatch() ">
    </div>
</template>

<!-- <script>
// 混合模式：通过选项配置 setup 属性定义组合式代码区域
export default {
    // 选项代码区
    // ……
    // setup 组合式代码区
    setup:function(){

        return {}
    }
}
</script> -->

<!-- 
    单文件组件的script 标签一旦定义了 setup 属性，表示内部的执行代码将全部作为组合式方法 setup 的内容  
        + 被 setup 描述的 script 标签会自动构建 return 功能 
-->
<script setup>
// 单组合式api定义语法

import { computed, ref , reactive, watch } from 'vue';

// ref 的使用 start
// let info = "info变量";
let info = ref("info变量");

let user = ref([1,2,3,4,5]);
const addUserItem = function(){
    user.value.push( Math.random() )
}

let color = ref("#0000ff");
// ref 的使用 end

// computed 的使用 start
let msg = ref("msg变量");
// let newMsg = computed(function(){
//     return msg.value + ".end"
// })
let newMsg = computed({
    get:function(){
        return msg.value + ".end"
    },
    set:function(nv){
        console.log("newMsg被修改",nv)
    }
})

const printNewMsg = function(){
    console.log("newMsg:",newMsg.value)
}
// computed 的使用 end

// reactive 的使用 start
let stu = reactive({
    name:"admin",
    password:"1234567"
})
const printStuName = function(){
    console.log("stu:",stu);
    console.log( stu.name )
}
const resetStu = function(){
    // stu = {
    //     name:"jack",
    //     password:"11111"
    // }
    stu = reactive({
        name:"jack",
        password:"11111"
    })
}
// reactive 的使用 end

// watch 的使用 start
let text = ref("text数据");
watch(text,function(nv,ov){
    console.log("text:",nv,ov)
})
let obj = ref({
    a:1,
    b:2
})

watch(obj,function(nv,ov){
    console.log("obj发送整体变化",nv,ov)
})

watch(obj,function(nv,ov){
    console.log("obj发送变化(深度监控)",nv,ov)
},{ deep:true })

const stopWatch = watch(function(){
    return obj.value.a
},function(nv,ov){
    console.log("obj.a发送变化",nv,ov)
})
console.log(stopWatch)

</script>

<style lang="scss" scoped>

</style>